package com.mc.lp.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.mc.lp.database.dao.ISportRecordDAO;
import com.mc.lp.database.entity.SportsRecordEntity;
import com.mc.lp.database.entity.helper.SportsRecordHelper;
import com.mc.lp.database.exception.ConcurrentAccessException;
import com.mc.lp.database.service.IAttachmentService;
import com.mc.lp.service.MicroCampusAbstractService;
import com.mc.lp.service.SportsService;
import com.mc.lp.shared.util.constants.ResponseStatus;
import com.mc.lp.shared.vo.EntitySaveResponse;
import com.mc.lp.shared.vo.IValueObject;
import com.mc.lp.shared.vo.SearchCriteriaVO;
import com.mc.lp.shared.vo.ServiceResponse;
import com.mc.lp.shared.vo.SportsRecordVO;
import com.mc.lp.shared.vo.StudentRecordVO;
import com.mc.lp.shared.vo.ValueObjectList;

/*
 * @author aphanda
 * @date Sep 21, 2014
 * @time 12:48:21 AM
 */

@Service
public class SportsServiceImpl extends MicroCampusAbstractService<SportsServiceImpl> implements
		SportsService {
	
	@Resource
	ISportRecordDAO sportsRecordDAO;
	

	@Resource
	IAttachmentService attachmentService;
	
	
	@Transactional
	public IValueObject saveSports(StudentRecordVO studentRecordVO) throws DataAccessException,	ConcurrentAccessException {
		ArrayList<SportsRecordVO> vos = new ArrayList<SportsRecordVO>();
		ServiceResponse<SportsRecordVO> sportsRecords = new ServiceResponse<SportsRecordVO>();
		SportsRecordHelper helper = new SportsRecordHelper();
		
		
		for (SportsRecordVO vo : studentRecordVO.getSportsActivities()) {
			EntitySaveResponse response = new EntitySaveResponse(vo.getSid(), "SportsActivities");
			
			SportsRecordEntity dbRecord = new SportsRecordEntity();
			SportsRecordEntity sports = helper.getEntity(vo);
			sports.setStudentEntity(studentRecordVO.getSearchCriteria().getStudentEntityId());

			if (!vo.isNewRow()) {
				if (vo.getSid() != 0) {
					dbRecord = sportsRecordDAO.get(vo.getSid());
					// Delete the entity which is marked as deleted on UI
					if (vo.isRowDeleted()) {
							try {
								sportsRecordDAO.delete(dbRecord);
								response.setStatus(ResponseStatus.SUCCESS);
								sportsRecords.setStatus(ResponseStatus.SUCCESS);
							} catch (DataAccessException e) {
								getLogger().error("saveSports()", e);
								response.setStatus(ResponseStatus.FAILED);
								response.setMsg(e.getMessage());
								
								sportsRecords.setStatus(ResponseStatus.FAILED);
								sportsRecords.setMsg(e.getMessage());
								
							} catch (ConcurrentAccessException e) {
								getLogger().error("saveSports()", e);
								response.setStatus(ResponseStatus.FAILED);
								response.setMsg(e.getMessage());
								sportsRecords.setStatus(ResponseStatus.FAILED);
								sportsRecords.setMsg(e.getMessage());
							}
						continue;
					}
					//AP this we need to do with reflection to avoid any kind or missed property situation.
				//	if (!dbRecord.equals(sports)) {
						try {
							helper.setEntity(vo, dbRecord);
							sportsRecordDAO.saveOrUpdate(dbRecord);
							response.setStatus(ResponseStatus.SUCCESS);
							sportsRecords.setStatus(ResponseStatus.SUCCESS);
						} catch (DataAccessException e) {
							getLogger().error("saveSports()", e);
							response.setStatus(ResponseStatus.FAILED);
							response.setMsg(e.getMessage());
							sportsRecords.setStatus(ResponseStatus.FAILED);
							sportsRecords.setMsg(e.getMessage());
						} catch (ConcurrentAccessException e) {
							getLogger().error("saveSports()", e);
							response.setStatus(ResponseStatus.FAILED);
							response.setMsg(e.getMessage());
							sportsRecords.setStatus(ResponseStatus.FAILED);
							sportsRecords.setMsg(e.getMessage());
						}
					//}
				}
			}else {
				sportsRecordDAO.save(sports);
				vo.setNewRow(false);
				response.setStatus(ResponseStatus.SUCCESS);
				sportsRecords.setStatus(ResponseStatus.SUCCESS);
				//add response to list and send back to ui
			}
			vos.add(vo);
		}
		
		sportsRecords.setResult(vos);
		return sportsRecords;

	}
	
	
	@Transactional
	public IValueObject getSportsByEntityIdGrade(StudentRecordVO studentRecordVO) {
		SearchCriteriaVO searchValue= studentRecordVO.getSearchCriteria();
		List<SportsRecordVO> resultVoList = new ArrayList<SportsRecordVO>();
		ServiceResponse<SportsRecordVO> response = new ServiceResponse<SportsRecordVO>();
		
		SportsRecordHelper helper = new SportsRecordHelper();
		
		Long entityId=searchValue.getStudentEntityId();
		int gradeId=searchValue.getGradeId();
		getLogger().info("getSportsByEntityIdGrade : entityId:"+entityId +", gradeId :"+gradeId);
		
		List<SportsRecordEntity> searchedRecords=sportsRecordDAO.fetchDetailsByEntityIdGrade(entityId,gradeId);
		if(CollectionUtils.isEmpty(searchedRecords)){
			response.setStatus(ResponseStatus.NOT_FOUND);
			getLogger().info("getSportsByEntityIdGrade : No record found in db for given params");
		}else{
			getLogger().info("getSportsByEntityIdGrade : Total records found :"+ searchedRecords);
			for(SportsRecordEntity entity: searchedRecords){
				SportsRecordVO vo = helper.getVO(entity);
				resultVoList.add(vo);
			}
			//get attachments to be displayed on ui
			ValueObjectList fileList = attachmentService.getAttachmentsWithoutData(searchValue);
			response.setExtraInfo(fileList);
			response.setStatus(ResponseStatus.SUCCESS);
		}
		response.setResult(resultVoList);
		return response;	
		
	}
	
	@Transactional
	public List<SportsRecordVO> getSportsByEntityIdGrade(Long entityId, int gradeId) {
		// TODO Auto-generated method stub

		List<SportsRecordEntity> list = sportsRecordDAO.fetchDetailsByEntityIdGrade(entityId,gradeId);

		SportsRecordHelper helper = new SportsRecordHelper();
		List<SportsRecordVO> voList = new ArrayList<SportsRecordVO>();

		for (SportsRecordEntity sportsRecordEntity : list) {
			voList.add(helper.getVO(sportsRecordEntity));
		}
		return voList;
	}
	

	@Transactional
	public List<SportsRecordVO> getSportsEntityId(Long entityId) {
		// TODO Auto-generated method stub
		List<SportsRecordEntity> list = sportsRecordDAO.fetchDetailsByEntityId(entityId);

		SportsRecordHelper helper = new SportsRecordHelper();
		List<SportsRecordVO> voList = new ArrayList<SportsRecordVO>();

		for (SportsRecordEntity sportsRecordEntity : list) {
			voList.add(helper.getVO(sportsRecordEntity));
		}
		return voList;
	}

	@Override
	public IValueObject getSportsByEntityId(StudentRecordVO studentRecordVO) {
		// TODO Auto-generated method stub
		return null;
	}


	@Transactional
	public List<SportsRecordVO> getSportsByGrades(Long studentEntity, List<Integer> gradeValueList) {
		// TODO Auto-generated method stub
		List<SportsRecordVO> voList = new ArrayList<SportsRecordVO>();
		List<SportsRecordEntity> sportsList = new ArrayList<SportsRecordEntity>();
		
		SportsRecordHelper helper  = new SportsRecordHelper();

		sportsList = sportsRecordDAO.fetchSportsByGrades(studentEntity,  gradeValueList);
		for (SportsRecordEntity entity : sportsList) {
			voList.add(helper.getVO(entity));
		}
		return voList;
	}
}
